package com.heu.blood.match.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heu.blood.application.entity.BloodApplicationEntity;
import com.heu.blood.common.utils.PageUtils;
import com.heu.blood.common.utils.Query;
import com.heu.blood.globalExceptionHandler.MyException;
import com.heu.blood.match.dao.PatientInformationDao;
import com.heu.blood.match.dictenum.AboBloodTypeEnum;
import com.heu.blood.match.entity.PatientBloodTypeDataEntity;
import com.heu.blood.match.entity.PatientInformationEntity;
import com.heu.blood.match.exception.QueryPatientInformationException;
import com.heu.blood.match.exception.TimeException;
import com.heu.blood.match.service.PatientInformationService;
import com.heu.blood.match.vo.PatientBloodTypeQueryVo;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.heu.blood.common.enums.CommonEnum.IF_SHOW;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lrz
 * @since 2023-07-05
 */
@Service
public class PatientInformationServiceImpl extends ServiceImpl<PatientInformationDao, PatientInformationEntity> implements PatientInformationService {

    @Autowired
    private PatientInformationDao patientInformationDao;

    /**
     * 分页查询患者信息表数据
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        // 构造patientInfomationEntity对象
        PatientInformationEntity patientInformationEntity = new PatientInformationEntity();
        if (Strings.isNotBlank((String) params.get("patientId"))){
            patientInformationEntity.setPatientId((String) params.get("patientId")); // 添加patientId
        }
        if (Strings.isNotBlank((String) params.get("aboBloodType"))){
            patientInformationEntity.setAboBloodType((String) params.get("aboBloodType")); // 添加aboBloodType
        }
        if (Strings.isNotBlank((String) params.get("rhBloodType"))){
            patientInformationEntity.setRhBloodType((String) params.get("rhBloodType")); // 添加rhBloodType
        }
        if (Strings.isNotBlank((String) params.get("patientType"))){
            patientInformationEntity.setPatientType((String) params.get("patientType")); // 添加patientType
        }
        // 构造条件构造器
        LambdaQueryWrapper<PatientInformationEntity> queryWrapper = new LambdaQueryWrapper<>();
        // 添加过滤条件
        queryWrapper.eq(Strings.isNotBlank(patientInformationEntity.getPatientId()), PatientInformationEntity::getPatientId, patientInformationEntity.getPatientId())
                    .eq(Strings.isNotBlank(patientInformationEntity.getAboBloodType()), PatientInformationEntity::getAboBloodType, patientInformationEntity.getAboBloodType())
                    .eq(Strings.isNotBlank(patientInformationEntity.getRhBloodType()), PatientInformationEntity::getRhBloodType, patientInformationEntity.getRhBloodType())
                    .eq(Strings.isNotBlank(patientInformationEntity.getPatientType()), PatientInformationEntity::getPatientType, patientInformationEntity.getPatientType())
                    .eq(PatientInformationEntity::getIfShow, IF_SHOW.code());

        String startTime = (String) params.get("startTime");
        String endTime = (String) params.get("endTime");

        if (Strings.isNotBlank(startTime) && Strings.isNotBlank(endTime)) {
            if (startTime.compareTo(endTime) > 0) {
                throw new MyException(TimeException.TIME_OUTLINE);
            }
        }
        if (Strings.isNotBlank(startTime)) {
            queryWrapper.ge(PatientInformationEntity::getGmtCreate, startTime);
        }
        if (Strings.isNotBlank(endTime)) {
            queryWrapper.le(PatientInformationEntity::getGmtCreate, endTime);
        }

        IPage<PatientInformationEntity> page = this.page(
                new Query<PatientInformationEntity>().getPage(params),
                queryWrapper
        );
        return new PageUtils(page);
    }

    /**
     * 根据patientId获取patientInformation表信息
     * @param patientId
     * @return
     */
    @Override
    public PatientInformationEntity queryWithPatientId(String patientId) {
        // 构造条件构造器
        LambdaQueryWrapper<PatientInformationEntity> queryWrapper = new LambdaQueryWrapper<>();
        // 添加过滤条件
        queryWrapper.eq(Strings.isNotBlank(patientId), PatientInformationEntity::getPatientId, patientId)
                    .eq(PatientInformationEntity::getIfShow, IF_SHOW.code());
        PatientInformationEntity patientInformationEntity = patientInformationDao.selectOne(queryWrapper);

        if (patientInformationEntity == null){
            throw new MyException(QueryPatientInformationException.DATA_NOT_FOUND);
        }

        return patientInformationEntity;
    }

    @Override
    public List<PatientInformationEntity> queryListWithPatientId(String patientId) {
        // 构造条件构造器
        LambdaQueryWrapper<PatientInformationEntity> queryWrapper = new LambdaQueryWrapper<>();
        // 添加过滤条件
        queryWrapper.eq(Strings.isNotBlank(patientId), PatientInformationEntity::getPatientId, patientId);
        List<PatientInformationEntity> entities = patientInformationDao.selectList(queryWrapper);

        return entities;
    }

    @Override
    public List<PatientBloodTypeDataEntity> patientBloodTypeQuery(PatientBloodTypeQueryVo patientBloodTypeQueryVo) {
        LambdaQueryWrapper<PatientInformationEntity> queryWrapper = Wrappers.lambdaQuery(PatientInformationEntity.class);

        queryWrapper.ge(patientBloodTypeQueryVo.getStartTime() != null, PatientInformationEntity::getGmtCreate, patientBloodTypeQueryVo.getStartTime())
                .le(patientBloodTypeQueryVo.getEndTime() != null, PatientInformationEntity::getGmtCreate, patientBloodTypeQueryVo.getEndTime())
                .eq(Strings.isNotBlank(patientBloodTypeQueryVo.getDepartment()),PatientInformationEntity::getDepartment,patientBloodTypeQueryVo.getDepartment());

        List<PatientInformationEntity> patientInformationEntityList=patientInformationDao.selectList(queryWrapper);
        int sum=patientInformationEntityList.size();



        // 3. 直接初始化结果列表
        List<PatientBloodTypeDataEntity> result = new ArrayList<>();
        for (AboBloodTypeEnum bloodType : AboBloodTypeEnum.values()) {
            PatientBloodTypeDataEntity entity = new PatientBloodTypeDataEntity();
            entity.setAboBloodType(bloodType.code());
            entity.setCount(0);
            entity.setPercentage("0.00%");
            result.add(entity);
        }
        // 4. 如果有数据则统计
        if (sum > 0) {
            // 统计各血型人数
            Map<String, Integer> bloodTypeCountMap = new HashMap<>();
            for (PatientInformationEntity patient : patientInformationEntityList) {
                String bloodType = patient.getAboBloodType();
                bloodTypeCountMap.put(bloodType, bloodTypeCountMap.getOrDefault(bloodType, 0) + 1);
            }

            double totalPercentage = 0.0;
            int lastIndex = result.size() - 1;

            for (int i = 0; i < result.size(); i++) {
                PatientBloodTypeDataEntity item = result.get(i);
                String type = item.getAboBloodType();
                int count = bloodTypeCountMap.getOrDefault(type, 0);
                item.setCount(count);

                if (i < lastIndex) {
                    double percent = (count * 100.0) / sum;
                    percent = Math.round(percent * 100.0) / 100.0; // 保留两位小数
                    totalPercentage += percent;
                    item.setPercentage(String.format("%.2f%%", percent));
                } else {
                    // 最后一项用 100 - 前面百分比之和，避免累计误差
                    double percent = 100.0 - totalPercentage;
                    item.setPercentage(String.format("%.2f%%", percent));
                }
            }

         /*   for (PatientBloodTypeDataEntity item : result) {
                String type = item.getAboBloodType();
                int count = bloodTypeCountMap.getOrDefault(type, 0);
                item.setCount(count);
                item.setPercentage(String.format("%.2f%%", (count * 100.0) / sum));
            }*/
        }else{
            throw new MyException(QueryPatientInformationException.DATA_NOT_FOUND);
        }
        return result;
    }

}
